#include "predicates.h"

namespace abc_query
{
    // Predicate基类实现
    std::shared_ptr<Predicate> Predicate::And(const std::shared_ptr<Predicate> &other) const
    {
        if (!other)
            return std::const_pointer_cast<Predicate>(shared_from_this());
        return std::make_shared<AndPredicate>(
            std::static_pointer_cast<const Predicate>(shared_from_this()),
            std::static_pointer_cast<const Predicate>(other));
    }

    std::shared_ptr<Predicate> Predicate::Or(const std::shared_ptr<Predicate> &other) const
    {
        if (!other)
            return std::const_pointer_cast<Predicate>(shared_from_this());
        return std::make_shared<OrPredicate>(
            std::static_pointer_cast<const Predicate>(shared_from_this()),
            std::static_pointer_cast<const Predicate>(other));
    }

    std::shared_ptr<Predicate> Predicate::Not() const
    {
        return std::make_shared<NotPredicate>(
            std::static_pointer_cast<const Predicate>(shared_from_this()));
    }

    // NodeTypePredicate实现
    NodeTypePredicate::NodeTypePredicate(abc::AbcNodeType type) : type_(type) {}

    bool NodeTypePredicate::testNode(const abc::AbcNodePtr &node) const
    {
        return node && node->type == type_;
    }

    bool NodeTypePredicate::testFunction(const abc::AbcFunctionPtr &) const
    {
        return false;
    }

    // ModulePredicate实现
    ModulePredicate::ModulePredicate(const std::string &module) : module_(module) {}

    bool ModulePredicate::testNode(const abc::AbcNodePtr &node) const
    {
        return node && pathMatchesModule(node->path, module_);
    }

    bool ModulePredicate::testFunction(const abc::AbcFunctionPtr &func) const
    {
        return func && pathMatchesModule(func->path, module_);
    }

    // PackagePredicate实现
    PackagePredicate::PackagePredicate(const std::string &pkg) : pkg_(pkg) {}

    bool PackagePredicate::testNode(const abc::AbcNodePtr &node) const
    {
        return node && pathMatchesPackage(node->path, pkg_);
    }

    bool PackagePredicate::testFunction(const abc::AbcFunctionPtr &func) const
    {
        return func && pathMatchesPackage(func->path, pkg_);
    }

    // FunctionNamePredicate实现
    FunctionNamePredicate::FunctionNamePredicate(const std::string &pattern)
        : pattern_(pattern) {}

    bool FunctionNamePredicate::testNode(const abc::AbcNodePtr &) const
    {
        return false;
    }

    bool FunctionNamePredicate::testFunction(const abc::AbcFunctionPtr &func) const
    {
        return func && nameMatchesPattern(func->name, pattern_);
    }

    // AndPredicate实现
    AndPredicate::AndPredicate(std::shared_ptr<const Predicate> left,
                               std::shared_ptr<const Predicate> right)
        : left_(std::move(left)), right_(std::move(right)) {}

    bool AndPredicate::testNode(const abc::AbcNodePtr &node) const
    {
        return left_->testNode(node) && right_->testNode(node);
    }

    bool AndPredicate::testFunction(const abc::AbcFunctionPtr &func) const
    {
        return left_->testFunction(func) && right_->testFunction(func);
    }

    // // OrPredicate实现
    OrPredicate::OrPredicate(std::shared_ptr<const Predicate> left,
                             std::shared_ptr<const Predicate> right)
        : left_(std::move(left)), right_(std::move(right)) {}

    bool OrPredicate::testNode(const abc::AbcNodePtr &node) const
    {
        return left_->testNode(node) || right_->testNode(node);
    }

    bool OrPredicate::testFunction(const abc::AbcFunctionPtr &func) const
    {
        return left_->testFunction(func) || right_->testFunction(func);
    }

    // // NotPredicate实现
    NotPredicate::NotPredicate(std::shared_ptr<const Predicate> pred)
        : predicate_(std::move(pred)) {}

    bool NotPredicate::testNode(const abc::AbcNodePtr &node) const
    {
        return !predicate_->testNode(node);
    }

    bool NotPredicate::testFunction(const abc::AbcFunctionPtr &func) const
    {
        return !predicate_->testFunction(func);
    }

} // namespace abc_query